前言
最主要的原因是前一阵生产环境出了一个问题
一个系统在某一天突然 redis 服务器内存激增
8G 的服务器一下子占到了内存 90% 以上
交换分区也占了很多
问题排查
首先想到的就是 redis 存储太多的东西
于是使用 redis-cli 登录 redis 集群
运行命令 info memory 查看所占用的内存情况
主要观察如下字段
- used_memory:Redis 实际分配的内存量。
- used_memory_human:以人类易读的格式显示 Redis 使用的内存量。
- used_memory_rss:Redis 从操作系统获取的物理内存量。
used_memory_human 字段返回了 5G
很明显,一个 8g 的服务器,内存占了 5G
主要原因就是存储过多导致的
但是我又观察了一下
使用 DBSIZE 这个命令去查询 redis 中到底存了多少键
结果发现只有 1500+ 个键
这就有问题了
他存储的键并不多
问题排查 2
于是就有了进一步的排查
进一步排查过程中
在网络上也查找了相关资料
查找大键是有各种脚本的
redis 本身查找大键的功能并不好用
但是由于一些限制
只能使用 redis 本身的功能
于是先执行了 redis-cli –bigkeys
会返回一个比较笼统的结果
然后在交换模式去使用
MEMORY USAGE key_name #使用这个命令去查找大键对应的内存情况
比较幸运的是
没用多久我就发了一个占了整整 5 亿字节的大键
5 亿字节相当于 5G 内存
几乎所有内存都是它占的
删除之后内存下降、swap 下降、问题解决
总结
我认为能写出这种逻辑,将所有内存存储在一个大键的人
最起码没有对程序的敬畏之心
虽然不会影响程序的正常运行
但是如此使用缓存
背离了程序设计的初衷
后来得知开发竟想永久保留此大键在内存中
让人感到无话可说
建议
REDIS 为单线程程序
对大键的处理无疑会阻碍其他连接的处理
且过大对于主从复制及其他 redis 内部操作均有影响
数据类型 | 推荐大小限制 | 最大支持 |
---|
String | 10 KB – 1 MB | 512 MB |
List | 10,000 – 100,000 个元素 | 40 亿 |
Hash | 不超过 100,000 个字段 | 40 亿 |
Set | 不超过 100,000 个元素 | 40 亿 |
Sorted Set | 不超过 100,000 个元素 | 40 亿 |